package com.pureut.production.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pureut.common.core.exception.GlobalException;
import com.pureut.common.core.web.domain.AjaxResult;
import com.pureut.common.security.utils.DictUtils;
import com.pureut.common.security.utils.SecurityUtils;
import com.pureut.production.domain.DegreasDocument;
import com.pureut.production.domain.DegreasOutput;
import com.pureut.production.domain.DegreasOutputDetail;
import com.pureut.production.domain.MaterialFinished;
import com.pureut.production.domain.dto.CalendarTeamDto;
import com.pureut.production.domain.dto.DegreasOutputDetailDto;
import com.pureut.production.domain.dto.QualityTemporaryDto;
import com.pureut.production.domain.system.domain.SysDocument;
import com.pureut.production.domain.system.dto.SysDocumentCheckDto;
import com.pureut.production.domain.vo.DegreasOutputDetailVo;
import com.pureut.production.domain.vo.UpdateByDegreasOutDetailVo;
import com.pureut.production.mapper.DegreasDocumentMapper;
import com.pureut.production.mapper.DegreasOutputDetailMapper;
import com.pureut.production.mapper.DegreasOutputMapper;
import com.pureut.production.mapper.MaterialFinishedMapper;
import com.pureut.production.service.DegreasDocumentService;
import com.pureut.production.service.DegreasOutputDetailService;
import com.pureut.production.service.DegreasOutputService;
import com.pureut.system.api.*;
import com.pureut.system.api.domain.SysDictData;
import com.pureut.system.api.vo.MaterialNumberAndBatchNoVo;
import com.pureut.system.api.vo.QualityInspectionDocumentVo;
import com.pureut.system.api.vo.UpdateGradeVo;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 脱脂产出明细实现层
 */
@Service
public class DegreasOutputDetailServiceImpl extends ServiceImpl<DegreasOutputDetailMapper, DegreasOutputDetail> implements DegreasOutputDetailService {

    /**
     * 脱脂产出mapper
     */
    @Resource
    DegreasOutputDetailMapper degreasOutputDetailMapper;

    /**
     * 排程fegin
     */
    @Resource
    SchedulingPlanFeignService schedulingPlanFeignService;

    /**
     * 基础模块fegin
     */
    @Resource
    FeignService feignService;

    /**
     * 仓库fegin
     */
    @Resource
    StorageFegin storageFegin;

    /**
     * 品质fegin
     */
    @Resource
    QualityFeginService qualityFeginService;

    /**
     * 公共物料mapper
     */
    @Resource
    MaterialFinishedMapper materialFinishedMapper;

    /**
     * 单据配置fegin
     */
    @Resource
    SystemDocumentFeignService systemDocumentFeignService;

    /**
     * 脱脂产出mapper
     */
    @Resource
    DegreasOutputMapper degreasOutputMapper;

    /**
     * 脱脂产出service
     */
    @Lazy
    @Resource
    DegreasOutputService degreasOutputService;

    /**
     * 脱脂制令单mapper
     */
    @Resource
    DegreasDocumentMapper degreasDocumentMapper;

    /**
     * 脱脂制令单service
     */
    @Resource
    DegreasDocumentService degreasDocumentService;

    /**
     * 脱脂产出明细列表
     *
     * @param degreasOrderNumber
     * @return
     */
    @Override
    public List<DegreasOutputDetailDto> getList(String degreasOrderNumber) {

        return degreasOutputDetailMapper.getDataList(degreasOrderNumber);
    }

    /**
     * 明细详情
     *
     * @param id
     * @return
     */
    @Override
    public DegreasOutputDetailDto getView(Long id) {

        return degreasOutputDetailMapper.getDataView(id);
    }

    /**
     * 条码修正
     *
     * @param degreasOutputDetailVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean codeCorrection(DegreasOutputDetailVo degreasOutputDetailVo) throws Exception {
        DegreasOutputDetail degreasOutputDetail = getById(degreasOutputDetailVo.getId());
        //获取缸号字典
        List<SysDictData> cylinderNumberArray = DictUtils.getDictCache("cylinder_number");
        Map<String, String> cylinderNumberMap = cylinderNumberArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //获取缸次字典
        List<SysDictData> cylinderOrderArray = DictUtils.getDictCache("cylinder_order");
        Map<String, String> cylinderOrderMap = cylinderOrderArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));

        //包号
        int i = 1;
        String newNumber = cylinderNumberMap.get(degreasOutputDetailVo.getCylinderNumber()) + cylinderOrderMap.get(degreasOutputDetailVo.getCylinderOrder());
        List<DegreasOutputDetail> degreasOutputDetails = degreasOutputDetailMapper.selectList(new QueryWrapper<DegreasOutputDetail>().lambda().eq(DegreasOutputDetail::getDegreasOrderNumber, degreasOutputDetail.getDegreasOrderNumber()).eq(DegreasOutputDetail::getCylinderNumber,newNumber).orderByDesc(DegreasOutputDetail::getCreateTime));

        if (degreasOutputDetails.size() > 0) {
            String cylinderNumber = degreasOutputDetails.get(0).getCylinderNumber();
            if (newNumber.equals(cylinderNumber)) {
                i = degreasOutputDetails.get(0).getPackNumber() + 1;
            }
        }
        DegreasOutput degreasOutput = degreasOutputMapper.selectOne(new QueryWrapper<DegreasOutput>().lambda().eq(DegreasOutput::getDegreasOrderNumber, degreasOutputDetail.getDegreasOrderNumber()));
        DegreasDocument degreasDocument = degreasDocumentMapper.selectOne(new QueryWrapper<DegreasDocument>().lambda().eq(DegreasDocument::getDegreasOrderNumber, degreasOutputDetailVo.getDegreasOrderNumber()));

        //获取跨天时间和班次
        AjaxResult ajaxResult = schedulingPlanFeignService.selectShiftLine(degreasOutput.getLineCode());
        if (ajaxResult == null) {
            throw new GlobalException("获取跨天时间和班次失败");
        }
        List<CalendarTeamDto> data = JSON.parseArray(JSON.toJSONString(ajaxResult.get("data")), CalendarTeamDto.class);

        Date crossSkyTime = null;
        String classDifference = null;
        for (CalendarTeamDto entity : data) {

            Date nowTime = new Date();
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(nowTime);
            Date time = calendar.getTime();
            //判断当前时间是否在开始时间和结束时间之内
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
            String time2 = simpleDateFormat.format(time);
            String time3 = entity.getTeamStartTime();
            String time4 = entity.getTeamEndTime();
            if (time2.compareTo(time3) > 0 && time2.compareTo(time4) < 0) {
                //获取班组
                classDifference = entity.getTeamInfo();
                //判断是否跨天,并判断当前时间小于开始时间
                if (entity.getTeamTranssky() == 1 && time2.compareTo(time3) < 0) {
                    //如果跨天就取前一天
                    Date date = new Date();
                    //得到日历
                    Calendar calendar1 = Calendar.getInstance();
                    //把当前时间赋给日历
                    calendar1.setTime(date);
                    //设置为前一天
                    calendar1.add(Calendar.DAY_OF_MONTH, -1);
                    //得到前一天的时间
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sf.format(calendar1.getTime());
                    //得到前一天的时间
                    crossSkyTime = new SimpleDateFormat("yyyy-MM-dd").parse(format);
                } else {
                    SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sf.format(new Date());
                    //得到前一天的时间
                    crossSkyTime = new SimpleDateFormat("yyyy-MM-dd").parse(format);
                }
            }
        }
        if (crossSkyTime == null && classDifference == null) {
            throw new GlobalException("未进行工厂日历配置");
        }
        if (degreasOutputDetail.getStatus() == 1) {
            String authorityCoding = feignService.getAuthorityCoding("productionTube:produAdm:degrproduc:degparaorder:list");
            degreasOutputDetail
                    .setTemplateId(degreasDocument.getDegreasMark())
                    .setMaterialCode(degreasOutputDetailVo.getMaterialCode())
                    .setCylinderNumber(degreasOutputDetailVo.getCylinderNumber() + degreasOutputDetailVo.getCylinderOrder())
                    .setPackNumber(i)
                    .setBatchNumber(authorityCoding + classDifference + "-" + degreasOutputDetailVo.getCylinderNumber())
                    .setGrossWeight(degreasOutputDetailVo.getGrossWeight())
                    .setNetWeight(degreasOutputDetailVo.getNetWeight())
                    .setOutputTime(new Date())
                    .setShift(classDifference)
                    .setCreateBy(SecurityUtils.getUsername())
                    .setRemark(degreasOutputDetailVo.getRemark())
                    .setCreateTime(new Date());
            boolean b = updateById(degreasOutputDetail);
            // 生成品质检验单

            Long menuId = feignService.getIdByMenuName("脱脂产出");
            AjaxResult infoDocumentConfigById = systemDocumentFeignService.getInfoDocumentConfigById(menuId);
            SysDocument sysDocument = JSON.parseObject(JSON.toJSONString(infoDocumentConfigById.get("data")), SysDocument.class);
            if (sysDocument.getDocCode() == null) {
                throw new GlobalException("未找到相应的检验项目，请前往“质量管理“---”检验配置”页配置");
            }
            List<SysDocumentCheckDto> documentCheckDtoList = sysDocument.getDocumentCheckDtoList();
            if (documentCheckDtoList.size() < 1) {
                throw new GlobalException("未进行检验单生成配置");
            }
            //通过物料编码获取物料类别
            MaterialFinished materialFinished = materialFinishedMapper.selectOne(new QueryWrapper<MaterialFinished>().lambda().eq(MaterialFinished::getMaterialCode, degreasOutput.getMaterialCode()));

            for (SysDocumentCheckDto checkDto : documentCheckDtoList) {

                QualityInspectionDocumentVo qualityInspectionDocumentVo = new QualityInspectionDocumentVo();
                qualityInspectionDocumentVo.setItemRank(checkDto.getCheckSubmit());
                qualityInspectionDocumentVo.setCategory(Integer.parseInt(materialFinished.getCategory()));
                qualityInspectionDocumentVo.setMaterialCategory(materialFinished.getMaterialType());
                qualityInspectionDocumentVo.setMaterialCode(degreasOutput.getMaterialCode());
                qualityInspectionDocumentVo.setBatchNo(degreasOutputDetail.getBatchNumber());
                qualityInspectionDocumentVo.setAssociatedNo(degreasOutput.getDegreasOrderNumber());
//                    qualityInspectionDocumentVo.setDifferentString(supplierManagement.getSupplierNum());
                qualityInspectionDocumentVo.setModeType(20);

                List<MaterialNumberAndBatchNoVo> materialNumberAndBatchNo = new ArrayList<>();
                MaterialNumberAndBatchNoVo materialNumberAndBatchNoVo = new MaterialNumberAndBatchNoVo();
                materialNumberAndBatchNoVo.setBatchNo(degreasOutputDetail.getBatchNumber());
                materialNumberAndBatchNoVo.setMaterialNumber(degreasOutputDetail.getMaterialNumber());
                materialNumberAndBatchNo.add(materialNumberAndBatchNoVo);
                qualityInspectionDocumentVo.setMaterialNumberAndBatchNo(materialNumberAndBatchNo);

                boolean b1 = qualityFeginService.addDegreas(qualityInspectionDocumentVo);
                if (!b1) {
                    throw new GlobalException("生成品质检验单失败!");
                }
            }
            return b;
        } else {
            throw new GlobalException("只能修正状态“待入库”的物料");
        }
    }

    /**
     * 修改明细检验状态，检验结果及物料等级(品质审核时候调用)
     *
     * @param updateByDegreasOutDetailVo
     * @return
     */
    @Override
    public boolean updateByDegreasOutDetail(UpdateByDegreasOutDetailVo updateByDegreasOutDetailVo) {
        //根据脱脂制令单号获取明细数据
        List<DegreasOutputDetail> degreasOutputDetails = degreasOutputDetailMapper.selectList(new QueryWrapper<DegreasOutputDetail>().lambda().eq(DegreasOutputDetail::getBatchNumber, updateByDegreasOutDetailVo.getBatchNumber()));

        //获取品质检验回传的物料信息
        List<QualityTemporaryDto> list = updateByDegreasOutDetailVo.getList();
        List<String> materialNumberList = new ArrayList<>();
        for (DegreasOutputDetail entityDegreas : degreasOutputDetails) {
            materialNumberList.add(entityDegreas.getMaterialNumber());
            for (QualityTemporaryDto entityTemporary : list) {
                if (entityDegreas.getMaterialNumber().equals(entityTemporary.getMaterialNumber())) {
                    entityDegreas.setCheckResult(Integer.parseInt(entityTemporary.getInspectionResults()));
//                    entityDegreas.setStatus(1);
                    entityDegreas.setCheckStatus(2);
                    entityDegreas.setMaterialLevel(Integer.parseInt(entityTemporary.getJudgmentGrade()));
                }
            }
        }
        //回传仓库数据物料等级
        UpdateGradeVo updateGradeVo = new UpdateGradeVo();
        updateGradeVo.setMaterialNumberList(materialNumberList);
        int materialLevel = updateByDegreasOutDetailVo.getMaterialLevel();
        updateGradeVo.setMaterialLevel(materialLevel);
        storageFegin.updateMaterialGrade(updateGradeVo);
        return updateBatchById(degreasOutputDetails);
//        if (b) {
//            //根据合格不合格将相关重量回传
//            DegreasOutput degreasOutput = degreasOutputMapper.selectOne(new QueryWrapper<DegreasOutput>().lambda().eq(DegreasOutput::getDegreasOrderNumber, updateByDegreasOutDetailVo.getDegreasOrderNumber()));
//            BigDecimal degreasOutputGoodWeight = new BigDecimal(String.valueOf(degreasOutput.getGoodOutputWeight()));
//            BigDecimal degreasOutputBadGoodWeight = new BigDecimal(String.valueOf(degreasOutput.getBadOutputWeight()));
//            //获取脱脂制令单数据
//            DegreasDocument degreasDocument = degreasDocumentMapper.selectOne(new QueryWrapper<DegreasDocument>().lambda().eq(DegreasDocument::getDegreasOrderNumber, degreasOutput.getDegreasOrderNumber()));
//            for (DegreasOutputDetail entity : degreasOutputDetails) {
//                if (entity.getCheckResult() == 1) {
//                    degreasOutputGoodWeight = degreasOutputGoodWeight.add(new BigDecimal(String.valueOf(entity.getNetWeight())));
//                    degreasOutput.setGoodOutputWeight(Double.parseDouble(degreasOutputGoodWeight.toString()));
//                    degreasDocument.setGoodOutputWeight(Double.parseDouble(degreasOutputGoodWeight.toString()));
//                } else {
//                    degreasOutputBadGoodWeight = degreasOutputBadGoodWeight.add(new BigDecimal(String.valueOf(entity.getNetWeight())));
//                    degreasOutput.setBadOutputWeight(Double.parseDouble(degreasOutputBadGoodWeight.toString()));
//                }
//            }
//            degreasDocumentService.updateById(degreasDocument);
//            degreasOutputService.updateById(degreasOutput);
//        }
//        return b;
    }

    /**
     * 修改明细检验物料等级(品质处理时候调用)
     *
     * @param updateByDegreasOutDetailVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateByDegreasOutDetailQuality(UpdateByDegreasOutDetailVo updateByDegreasOutDetailVo) {
        //获取脱脂明细数据
        List<DegreasOutputDetail> degreasOutputDetails = degreasOutputDetailMapper.selectList(new QueryWrapper<DegreasOutputDetail>().lambda().eq(DegreasOutputDetail::getBatchNumber, updateByDegreasOutDetailVo.getBatchNumber()));
        //获取脱脂产出数据
        DegreasOutput degreasOutput = degreasOutputMapper.selectOne(new QueryWrapper<DegreasOutput>().lambda().eq(DegreasOutput::getDegreasOrderNumber, degreasOutputDetails.get(0).getDegreasOrderNumber()));
        BigDecimal bigDecimal = new BigDecimal(0);
        List<String> materialNumberList = new ArrayList<>();
        for (DegreasOutputDetail entity : degreasOutputDetails) {
            materialNumberList.add(entity.getMaterialNumber());
            bigDecimal = bigDecimal.add(new BigDecimal(String.valueOf(entity.getNetWeight())));
            entity.setCheckStatus(2);
            entity.setCheckResult(2);
            //3返工   4报废
            if (updateByDegreasOutDetailVo.getMaterialLevel() == 3) {
                entity.setMaterialLevel(updateByDegreasOutDetailVo.getMaterialLevel());
            } else {
                entity.setMaterialLevel(2);
            }
        }
        //将对应的净重累加至不量产出重量
        if(degreasOutput.getBadOutputWeight() == 0){
            degreasOutput.setBadOutputWeight(Double.parseDouble(bigDecimal.toString()));
        }else {
            BigDecimal add = new BigDecimal(String.valueOf(degreasOutput.getBadOutputWeight())).add(bigDecimal);
            degreasOutput.setBadOutputWeight(Double.parseDouble(add.toString()));
        }
        degreasOutputService.updateById(degreasOutput);
        //回传脱脂制令单不良重量
        DegreasDocument degreasDocument = degreasDocumentMapper.selectOne(new QueryWrapper<DegreasDocument>().lambda().eq(DegreasDocument::getDegreasOrderNumber, degreasOutput.getDegreasOrderNumber()));
        if(degreasDocument.getBadOutputWeight() == 0){
            degreasDocument.setBadOutputWeight(Double.parseDouble(bigDecimal.toString()));
        }else {
            BigDecimal add = new BigDecimal(String.valueOf(degreasDocument.getBadOutputWeight())).add(bigDecimal);
            degreasDocument.setBadOutputWeight(Double.parseDouble(add.toString()));
        }
        degreasDocumentService.updateById(degreasDocument);
        //回传仓库数据物料等级
        UpdateGradeVo updateGradeVo = new UpdateGradeVo();
        updateGradeVo.setMaterialNumberList(materialNumberList);
        int materialLevel = updateByDegreasOutDetailVo.getMaterialLevel();
        updateGradeVo.setMaterialLevel(materialLevel);
        storageFegin.updateMaterialGrade(updateGradeVo);

        return updateBatchById(degreasOutputDetails);
    }

    /**
     * 根据物料号码查询脱脂产出明细详情
     * @param materialNumber
     * @return
     */
    @Override
    public DegreasOutputDetail selectMaterialNumberInfo(String materialNumber) {
        return degreasOutputDetailMapper.selectOne(new QueryWrapper<DegreasOutputDetail>().lambda().eq(DegreasOutputDetail::getMaterialNumber, materialNumber));
    }

    /**
     * 查询脱脂产出明细
     * @param degreasOrderNumber
     * @return
     */
    @Override
    public List<DegreasOutputDetailDto> getDetailList(String degreasOrderNumber) {
        return degreasOutputDetailMapper.getDetailList(degreasOrderNumber);
    }

    /**
     * 查询脱脂产出明细
     * @param materialNumber
     * @return
     */
    @Override
    public DegreasOutputDetailDto selectDetailListMaterialNumber(String materialNumber) {
        return degreasOutputDetailMapper.selectDetailListMaterialNumber(materialNumber);
    }
}
